// 定义一个包含若干中文文档的数组
const docs = [
    '人工智能正在改变世界。',
    '机器学习和深度学习是人工智能的重要分支。',
    '猫和狗是常见的宠物。',
    'AI可以帮助医生诊断疾病。',
    '篮球是一项受欢迎的运动。',
    '人工智能与大数据密不可分。',
    '天气预报依赖于大量数据分析。'
];
// 分词函数：将文本按中文、字母、数字和空格分割成词语
function tokenize(text) {
    // 先去除除中文、字母、数字、空格以外的字符，再按空格分割，最后过滤掉空字符串
    return text.replace(/[^\u4e00-\u9fa5a-zA-Z0-9 ]/g, '').split(/\s+/).filter(Boolean);
}

// 计算IDF（逆文档频率）：衡量关键词在所有文档中的稀有程度
function computeIDF(term, docs) {
    // 统计包含该关键词的文档数
    let df = 0;
    for (const doc of docs) {
        // 如果该文档分词后包含该关键词，则df加1
        if (tokenize(doc).includes(term)) df++;
    }
    // 按照BM25的IDF公式计算并返回
    return Math.log((docs.length - df + 0.5) / (df + 0.5) + 1);
}

// BM25打分函数：计算某个文档与查询关键词的相关性得分
function bm25Score(query, doc, docs, k1 = 1.5, b = 0.75) {
    // 对查询进行分词
    const terms = tokenize(query);
    // 对文档进行分词
    const docTerms = tokenize(doc);
    // 当前文档的长度
    const docLen = docTerms.length;
    // 所有文档的平均长度
    const avgdl = docs.reduce((sum, d) => sum + tokenize(d).length, 0) / docs.length;
    // 初始化得分
    let score = 0;
    // 遍历每个查询词
    for (const q of terms) {
        // 统计该查询词在当前文档中出现的次数
        const fq = docTerms.filter(t => t === q).length;
        // 如果该词在文档中未出现，跳过
        if (fq === 0) continue;
        // 计算该词的IDF
        const idf = computeIDF(q, docs);
        // 按照BM25公式累加得分
        score += idf * fq * (k1 + 1) / (fq + k1 * (1 - b + b * docLen / avgdl));
    }
    // 返回最终得分
    return score;
}

// 展示排序结果的函数
function showResults() {
    // 获取用户输入的查询关键词，并去除首尾空格 人工智能
    const query = document.getElementById('query-input').value.trim();
    // 获取用于显示结果的DOM元素
    const resultList = document.getElementById('result-list');
    // 如果没有输入关键词，提示用户输入
    if (!query) {
        resultList.innerHTML = '请输入关键词';
        return;
    }
    // 对每个文档计算BM25得分，并过滤掉得分为0的文档
    const scored = docs.map((doc, idx) => ({
        doc,
        score: bm25Score(query, doc, docs)
    }))
    // 按得分从高到低排序
    scored.sort((a, b) => b.score - a.score);
    // 如果没有相关内容，提示用户
    if (scored.length === 0) {
        resultList.innerHTML = '没有找到相关内容';
        return;
    }
    // 将排序后的结果渲染到页面
    resultList.innerHTML = scored.map(item => `
      
        ${item.doc}
        分数：${item.score.toFixed(3)}
      
    `).join('');
}

// 给"相关性排序"按钮绑定点击事件，点击时执行showResults函数
document.getElementById('search-btn').onclick = showResults;